﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;

using System.Windows.Data;
using Microsoft.Practices.Unity;

using Baosight.Platform.Core;
using Baosight.Platform.Core.UI.Controls;
using Baosight.Platform.Core.ServiceModel;

using Baosight.ZNH.ZMCA.UI.Controls;
using Baosight.ZNH.ZMCA.UI.Utils;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Gauges;
using Telerik.Windows.Controls.Charting;
using Baosight.ZNH.ZMCA.UI.Model;

namespace Baosight.ZNH.ZMCA.UI
{
    public partial class ZMCA14 : EFView
    {
        public ZMCA14Controler controler = new ZMCA14Controler();

        /// <summary>
        /// 构造函数
        /// </summary>
        public ZMCA14()
        {
            InitializeComponent();

            this.lstView.FontSize = Common.FontsizeSetting;

            InitGaugeData(this.indexGauge);
            InitChartData(this.tendChart);
            InitRadTreeListData(this.lstView);
        }

        #region 填充控件数据

        private void InitGaugeData(SingleCircleGauge gauge)
        {
            controler.GetGaugeData(gauge);
        }

        private void InitChartData(RadChart chart)
        {
            controler.GetChartData(chart);
        }

        private void InitRadTreeListData(RadTreeListView lstView)
        {
            controler.GetRadTreeListData(lstView);
        }

        #endregion

    }

    /// <summary>
    /// 界面控件显示控制类ZMCA14Controler
    /// </summary>
    public class ZMCA14Controler
    {
        private SingleCircleGauge gauge;
        private RadChart chart;
        private RadTreeListView lstView;

        public static ZMCA03DetailItem result = null;     //用于刷新所有月份前三位的颜色

        public ZMCA14Controler()
        {

        }

        #region 查询加载Gauge图

        /// <summary>
        /// 初始化指标图，查询数据
        /// </summary>
        public void GetGaugeData(SingleCircleGauge gauge)
        {
            this.gauge = gauge;
            this.gauge.gaugeTitle.Text = "本月材料消耗";

            EIInfo eiInfo = new EIInfo();
            eiInfo.Set("service", "ZMCA14");
            eiInfo.Set("method", "queryByIndex");

            HttpServiceAgent agent = new HttpServiceAgent();
            agent.CallService(eiInfo, QueryGaugeDataDoWorkCompleted);
        }

        /// <summary>
        /// 查询指标图数据回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryGaugeDataDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.Status == -1)
            {
                return;
            }
            else
            {
                EIBlock result = e.EIInfo.GetBlock("result");
                double val = 0.0;

                if (result != null && result.GetRowCount() > 0)
                {
                    val = Convert.ToDouble(result.GetRow(0)["fdPrice"].ToString().Trim());
                }

                string unit = GetUnit(ref val);

                //设置最大值
                double maxValueRate = 1.5;
                this.gauge.centerGaugeDescription.Text = unit;
                this.gauge.centerNeedle.Value = val;
                this.gauge.centerControler.IsReverse = false;

            }
        }

        /// <summary>
        /// 根据传入值计算单位
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private string GetUnit(ref double value)
        {
            string unit = "";
            int count = 0;

            if (value < 1000)
            {
                return "元";
            }
            else
            {
                value = value / 1000;
            }

            while (value >= 10)
            {
                value = value / 10;
                count++;
            }

            switch (count)
            {
                case 1:
                    unit = "万元";
                    break;
                case 2:
                    unit = "十万元";
                    break;
                case 3:
                    unit = "百万元";
                    break;
                case 4:
                    unit = "千万元";
                    break;
                case 5:
                    unit = "亿元";
                    break;
                case 6:
                    unit = "十亿元";
                    break;
                case 7:
                    unit = "百亿元";
                    break;
                case 8:
                    unit = "千亿元";
                    break;
                default:
                    unit = "万元";
                    break;
            }

            return unit;
        }

        #endregion

        #region 查询加载Chart图

        /// <summary>
        /// 初始化趋势图，查询数据
        /// </summary>
        public void GetChartData(RadChart chartIndex)
        {
            this.chart = chartIndex;

            EIInfo eiInfo = new EIInfo();
            eiInfo.Set("service", "ZMCA14");
            eiInfo.Set("method", "queryByChart");

            HttpServiceAgent agent = new HttpServiceAgent();
            agent.CallService(eiInfo, QueryChartDataDoWorkCompleted);
        }

        /// <summary>
        /// 查询趋势图数据回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryChartDataDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.Status == -1)
            {
                return;
            }
            else
            {
                EIBlock chartBlock = e.EIInfo.GetBlock("chart");

                int currentYear = int.Parse(e.EIInfo.Get("year").ToString());
                int currentMonth = int.Parse(e.EIInfo.Get("month").ToString());

                this.chart.DefaultView.ChartTitle.FontSize = Common.FontsizeSetting;
                this.chart.DefaultView.ChartArea.FontSize = Common.FontsizeSetting;
                this.chart.DefaultView.ChartLegend.FontSize = Common.FontsizeSetting;

                this.chart.DefaultView.ChartTitle.Content = currentYear + "材料消耗趋势分析";
                this.chart.DefaultSeriesDefinition.ShowItemToolTips = true;
                this.chart.DefaultSeriesDefinition.LegendDisplayMode = LegendDisplayMode.DataPointLabel;
                chart.DefaultView.ChartLegend.Header = "单位：万元";

                this.chart.DefaultView.ChartArea.AxisY.MajorGridLinesVisibility = Visibility.Visible;
                this.chart.DefaultView.ChartArea.AxisY.MinorGridLinesVisibility = Visibility.Visible;
                this.chart.DefaultView.ChartArea.AxisY.StripLinesVisibility = Visibility.Visible;

                this.chart.SeriesMappings.Add(GenerateSeriesForChart("计划", 0, "Bar Series"));
                this.chart.SeriesMappings.Add(GenerateSeriesForChart("实际", 1, "Bar Series"));
                this.chart.SeriesMappings.Add(GenerateSeriesForChart("趋势", 1, "Line Series"));

                List<List<ChartData>> tendChartItemsSource = new List<List<ChartData>>();
                List<ChartData> lstActual = new List<ChartData>();
                List<ChartData> lstPlan = new List<ChartData>();
                //List<ChartData> lstTend = new List<ChartData>();

                for (int i = 1; i <= currentMonth; i++)
                {
                    lstPlan.Add(new ChartData(i + "月", 0));
                    lstActual.Add(new ChartData(i + "月", 0));
                }

                foreach (var item in chartBlock.Rows)
                {
                    if (item["fdKeyId"].ToString().Trim() == string.Empty)    //fdKeyId用于区分是计划消耗还是实际消耗
                    {
                        continue;
                    }

                    int dataType = Common.GetIntValue(item["fdKeyId"]);

                    if (dataType == 0)      //0 计划消耗
                    {
                        int month = Common.GetIntValue(item["fdMonth"]);

                        if (month == 0 || month > currentMonth)
                            continue;
                        else
                            lstPlan[month - 1].DataValue = Common.GetDecimalValue(item["fdPrice"]);
                    }
                    else if (dataType == 1)     // 1 实际消耗
                    {
                        int month = Common.GetIntValue(item["fdMonth"]);

                        if (month == 0 || month > currentMonth)
                            continue;
                        else
                        {
                            lstActual[month - 1].DataValue = Common.GetDecimalValue(item["fdPrice"]);
                            //lstTend[month - 1].DataValue = Common.GetDecimalValue(item["fdPrice"]);
                        }
                    }
                }

                tendChartItemsSource.Add(lstPlan);
                tendChartItemsSource.Add(lstActual);
                //tendChartItemsSource.Add(lstTend);
                this.chart.ItemsSource = tendChartItemsSource;
            }
        }

        /// <summary>
        /// 添加Chart图数据序列定义
        /// </summary>
        /// <param name="label"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private SeriesMapping GenerateSeriesForChart(string label, int index, string defType)
        {
            SeriesMapping series = new SeriesMapping();

            switch (defType)
            {
                case "Bar Series":
                    series.SeriesDefinition = new BarSeriesDefinition();
                    break;
                case "Line Series":
                    //series.SeriesDefinition = new LineSeriesDefinition();
                    series.SeriesDefinition = new SplineSeriesDefinition();
                    break;
                default:
                    break;
            }

            series.CollectionIndex = index;
            series.LegendLabel = label;
            series.SeriesDefinition.ShowItemLabels = false;
            series.SeriesDefinition.ShowItemToolTips = true;
            series.SeriesDefinition.ShowZeroValuesLabels = true;
            series.ItemMappings.Add(new ItemMapping("Date", DataPointMember.XCategory));
            series.ItemMappings.Add(new ItemMapping("DataValue", DataPointMember.YValue));
            series.SeriesDefinition.InteractivitySettings.HoverScope = InteractivityScope.Series;
            series.SeriesDefinition.InteractivitySettings.SelectionScope = InteractivityScope.Series;
            series.SeriesDefinition.InteractivitySettings.SelectionMode = ChartSelectionMode.Multiple;

            return series;
        }

        #endregion

        #region 查询加载RadTreeListView及数据

        /// <summary>
        /// 查询RadTreeListView控件数据
        /// </summary>
        /// <param name="lstView"></param>
        public void GetRadTreeListData(RadTreeListView lstView)
        {
            this.lstView = lstView;

            EIInfo eiInfo = new EIInfo();
            eiInfo.Set("service", "ZMCA14");
            eiInfo.Set("method", "queryByListView");

            HttpServiceAgent agent = new HttpServiceAgent();
            agent.CallService(eiInfo, QueryListViewDataDoWorkCompleted);
        }

        /// <summary>
        /// 查询RadTreeListView控件数据回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryListViewDataDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.Status == -1)
            {
                return;
            }
            else
            {
                EIInfo outInfo = e.EIInfo;
                EIBlock departmentPlan = outInfo.GetBlock("departmentPlan");
                EIBlock departmentActual = outInfo.GetBlock("departmentActual");

                EIBlock workfacePlan = outInfo.GetBlock("workfacePlan");
                EIBlock workfaceActual = outInfo.GetBlock("workfaceActual");

                EIBlock roadwayPlan = outInfo.GetBlock("roadwayPlan");
                EIBlock roadwayActual = outInfo.GetBlock("roadwayActual");

                EIBlock materialTypePlan = outInfo.GetBlock("materialTypePlan");
                EIBlock materialTypeActual = outInfo.GetBlock("materialTypeActual");

                int currentMonth = int.Parse(outInfo.Get("month").ToString().Trim());
                int currentYear = int.Parse(outInfo.Get("year").ToString().Trim());

                //将超过当前月的列隐藏
                for (int i = 12 - currentMonth + 1; i > 1; i--)
                {
                    var col = this.lstView.Columns[i];
                    col.IsVisible = false;
                }

                //构造树目录结构
                List<ZMCA03DetailItem> itemsSource = new List<ZMCA03DetailItem>();

                ZMCA03DetailItem yearItem = new ZMCA03DetailItem();
                ZMCA03DetailItem yearDepartmentItem = new ZMCA03DetailItem();
                ZMCA03DetailItem yearWorkFaceItem = new ZMCA03DetailItem();
                ZMCA03DetailItem yearRoadWayItem = new ZMCA03DetailItem();
                ZMCA03DetailItem yearMaterialTypeItem = new ZMCA03DetailItem();

                itemsSource.Add(yearItem);
                Type itemType = yearItem.GetType();
                yearItem.Name = "全矿";

                yearDepartmentItem.Name = "所有单位";
                yearItem.Items.Add(yearDepartmentItem);

                yearWorkFaceItem.Name = "所有工作面";
                yearItem.Items.Add(yearWorkFaceItem);

                yearRoadWayItem.Name = "所有巷道";
                yearItem.Items.Add(yearRoadWayItem);

                yearMaterialTypeItem.Name = "所有材料类型";
                yearItem.Items.Add(yearMaterialTypeItem);

                //生成单位汇总子记录
                AddLevelChildItemByBlock(departmentPlan, departmentActual, yearDepartmentItem, itemType, "0");
                AddOtherChildItemByBlock(workfacePlan, workfaceActual, yearWorkFaceItem, itemType);
                AddOtherChildItemByBlock(roadwayPlan, roadwayActual, yearRoadWayItem, itemType);
                AddLevelChildItemByBlock(materialTypePlan, materialTypeActual, yearMaterialTypeItem, itemType, "1");
                yearItem.CopyData(yearDepartmentItem);
                this.lstView.ItemsSource = itemsSource;
            }
        }

        /// <summary>
        /// 为RadTreeListView控件添加具有层级结构的数据
        /// </summary>
        /// <param name="plan"></param>
        /// <param name="actual"></param>
        /// <param name="parentDetailItem"></param>
        /// <param name="itemType"></param>
        private void AddLevelChildItemByBlock(EIBlock plan, EIBlock actual, ZMCA03DetailItem parentDetailItem, Type itemType, string index)
        {
            IDictionary<string, ZMCA03DetailItem> dic = new Dictionary<string, ZMCA03DetailItem>();
            ZMCA03DetailItem detailItem = null;

            //1. 先构造记录并填入计划消耗
            foreach (var item in plan.Rows)
            {
                string year = Common.GetStringValue(item["fdYear"]);
                string month = Common.GetStringValue(item["fdMonth"]);
                string itemUniqueName = Common.GetStringValue(item["fdKeyId"]);

                if(itemUniqueName.Trim() == string.Empty)
                    continue;

                if (detailItem == null || detailItem.UniqueName != itemUniqueName)
                {
                    detailItem = new ZMCA03DetailItem();
                    dic.Add(itemUniqueName, detailItem);

                    if (Common.GetIntValue(item["fdLevel"]) == 1)
                    {
                        parentDetailItem.Items.Add(detailItem);
                    }
                    else
                    {
                        if (dic.ContainsKey(item["fdParentId"].ToString()))
                        {
                            dic[item["fdParentId"].ToString()].Items.Add(detailItem);
                        }
                        else
                        {
                            parentDetailItem.Items.Add(detailItem);
                            //单位层级有问题，找不到父亲单位
                        }
                    }

                    detailItem.UniqueName = itemUniqueName;
                    detailItem.Name = item["fdName"].ToString();

                    if (index.Equals("1"))      //fdType类型标记材料类型大类
                        detailItem.fdType = "1";
                }

                //string year = "2011";
                if (year.Trim() == string.Empty || month.Trim() == string.Empty)
                {
                    continue;
                }

                PropertyInfo pi = itemType.GetProperty("M" + month);
                pi.SetValue(detailItem, decimal.Parse(item["fdPrice"].ToString()), null);
                //PropertyInfo pi = itemType.GetProperty("M" + i++.ToString());
                //pi.SetValue(detailItem, decimal.Parse("99.99"), null);
            }

            //2. 填入实际消耗
            foreach (var item in actual.Rows)
            {
                string year = Common.GetStringValue(item["fdYear"]);
                string month = Common.GetStringValue(item["fdMonth"]);
                string itemUniqueName = Common.GetStringValue(item["fdKeyId"]);

                //string year = "2011";
                if (itemUniqueName.Trim() == string.Empty)
                {
                    continue;
                }

                detailItem = dic[itemUniqueName];

                if (year.Trim() == string.Empty || month.Trim() == string.Empty)
                {
                    continue;
                }


                PropertyInfo pi_Revise = itemType.GetProperty("M" + month + "_Revise");
                pi_Revise.SetValue(detailItem, decimal.Parse(item["fdPrice"].ToString()), null);
            }

            //计算每个月和全年的前三位实际消耗量
            result = CalFrontThreeComsumption(dic);

            //将具有层级关系的节点消耗合并
            ZMCA03DetailItem.SummarizedChildItemData(parentDetailItem);
        }

        /// <summary>
        /// 为RadTreeListView控件添加不具有层级结构的数据
        /// </summary>
        /// <param name="plan"></param>
        /// <param name="actual"></param>
        /// <param name="parentDetailItem"></param>
        /// <param name="itemType"></param>
        private void AddOtherChildItemByBlock(EIBlock plan, EIBlock actual, ZMCA03DetailItem parentDetailItem, Type itemType)
        {
            Dictionary<string, ZMCA03DetailItem> dic = new Dictionary<string, ZMCA03DetailItem>();
            ZMCA03DetailItem detailItem = null;

            //1. 先构造记录并填入计划消耗
            foreach (var item in plan.Rows)
            {
                string year = Common.GetStringValue(item["fdYear"]);
                string month = Common.GetStringValue(item["fdMonth"]);
                string itemUniqueName = Common.GetStringValue(item["fdKeyId"]);

                //string year = "2011";
                if (itemUniqueName.Trim() == string.Empty)
                {
                    continue;
                }

                if (detailItem == null || detailItem.UniqueName != itemUniqueName)
                {
                    detailItem = new ZMCA03DetailItem();
                    dic.Add(itemUniqueName, detailItem);

                    parentDetailItem.Items.Add(detailItem);

                    detailItem.UniqueName = itemUniqueName;
                    detailItem.Name = item["fdName"].ToString();
                }

                if (year.Trim() == string.Empty || month.Trim() == string.Empty)
                {
                    continue;
                }

                PropertyInfo pi = itemType.GetProperty("M" + month);
                pi.SetValue(detailItem, decimal.Parse(item["fdPrice"].ToString()), null);
                //PropertyInfo pi = itemType.GetProperty("M" + i++.ToString());
                //pi.SetValue(detailItem, decimal.Parse("99.99"), null);
            }

            //2. 填入实际消耗
            foreach (var item in actual.Rows)
            {
                string year = Common.GetStringValue(item["fdYear"]);
                string month = Common.GetStringValue(item["fdMonth"]);
                string itemUniqueName = Common.GetStringValue(item["fdKeyId"]);

                //string year = "2011";
                if (itemUniqueName.Trim() == string.Empty)
                {
                    continue;
                }

                detailItem = dic[itemUniqueName];

                if (year.Trim() == string.Empty || month.Trim() == string.Empty)
                {
                    continue;
                }

                PropertyInfo pi_Revise = itemType.GetProperty("M" + month + "_Revise");
                pi_Revise.SetValue(detailItem, decimal.Parse(item["fdPrice"].ToString()), null);
                //PropertyInfo pi_Revise = itemType.GetProperty("M" + i++.ToString() + "_Revise");
                //pi_Revise.SetValue(detailItem, decimal.Parse("55.55"), null);
            }

            ZMCA03DetailItem.SummarizedChildItemData(parentDetailItem);
        }

        #endregion

        #region 计算每个月和全年前三位的实际消耗

        /// <summary>
        /// 计算每个月和全年前三位的实际消耗
        /// </summary>
        /// <param name="dic"></param>
        /// <returns></returns>
        private ZMCA03DetailItem CalFrontThreeComsumption(IDictionary<string, ZMCA03DetailItem> dic)
        {
            ZMCA03DetailItem result = new ZMCA03DetailItem();
            Type itemType = result.GetType();

            for (int i = 1; i <= 12; i++)
            {
                IList<ZMCA03DetailItem> sortedList = sortedByMonth(dic, "M" + i.ToString());
                decimal third = GetThirdValue(sortedList, "M" + i.ToString());

                PropertyInfo pi = itemType.GetProperty("M" + i.ToString() + "_Revise");
                pi.SetValue(result, third, null);
            }

            IList<ZMCA03DetailItem> sortedByTotalYear = sortedByMonth(dic, "DependantTotalYear");
            decimal totalYearThird = GetThirdValue(sortedByTotalYear, "DependantTotalYear");

            PropertyInfo totalYearPi = itemType.GetProperty("DependantTotalYear_Revise");
            totalYearPi.SetValue(result, totalYearThird, null);

            return result;
        }

        /// <summary>
        /// 按月份的实际消耗降序排序（利用反射特性）
        /// </summary>
        /// <param name="dic"></param>
        /// <param name="month"></param>
        /// <returns></returns>
        private IList<ZMCA03DetailItem> sortedByMonth(IDictionary<string, ZMCA03DetailItem> dic, string index)
        {
            index = index + "_Revise";
            Type itemType = (new ZMCA03DetailItem()).GetType();

            IList<ZMCA03DetailItem> sortedList = (from it in dic.Values orderby itemType.GetProperty(index).GetValue(it, null) 
                                                  descending select it).ToList<ZMCA03DetailItem>();

            return sortedList;
        }

        /// <summary>
        /// 获取排序后序列第三大的值（利用反射特性）
        /// </summary>
        /// <param name="sortedItems"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private decimal GetThirdValue(IList<ZMCA03DetailItem> sortedItems, string index)
        {
            ZMCA03DetailItem item = new ZMCA03DetailItem();
            Type itemType = item.GetType();

            if (sortedItems.Count >= 3)
            {
                item = sortedItems[2];
            }
            else
            {
                if (sortedItems.Count == 2)
                {
                    item = sortedItems[1];
                }
                else if (sortedItems.Count == 1)
                {
                    item = sortedItems[0];
                }
            }

            //PropertyInfo是根据某类型的属性的字符串形式找到属性的元数据信息，也就是反射的应用
            PropertyInfo pi = itemType.GetProperty(index +"_Revise");
            decimal result = Common.GetDecimalValue(pi.GetValue(item, null));

            return result;
        }

        #endregion

    }

    #region RadTreeListView控件数据显示控制类DataColorConverter

    public class DataColorConverter : IValueConverter
    {
        /// <summary>
        /// 数据显示转换函数
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            ZMCA03DetailItem item = value as ZMCA03DetailItem;
            ZMCA03DetailItem compare = ZMCA14Controler.result;      //对所有月份进行比较

            if (item.Items.Count == 0 && "1".Equals(item.fdType) && compare != null)
            {
                string para = parameter == null ? "" : parameter.ToString().Trim();

                Type itemType = item.GetType();
                PropertyInfo pi = itemType.GetProperty(para);
                decimal itemValue = Common.GetDecimalValue(pi.GetValue(item, null));
                decimal cmpValue = Common.GetDecimalValue(pi.GetValue(compare, null));

                return GetForegroundColor(itemValue, cmpValue);
            }
            else
            {
                return "Black";
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }

        private string GetForegroundColor(decimal item, decimal dest)
        {
            if (item > Decimal.Zero && item >= dest)
            {
                return "Red";
            }
            else
            {
                return "Black";
            }
        }

    }

    #endregion

}
